import { Skia } from "@shopify/react-native-skia";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import type { SharedValue } from "react-native-reanimated";
import Animated, {
  useAnimatedStyle,
  useSharedValue,
} from "react-native-reanimated";
import { type CropRect } from "./SkiaImageEditor";

/**
 * 裁剪手势处理器组件的props接口
 * @property cropRect - 裁剪框的位置和尺寸信息（共享值，可实时更新）
 * @property imageSize - 图片的原始宽高尺寸，用于边界限制
 * @property matrix - 变换矩阵（共享值，用于统一控制位置）
 * @property disabled - 是否禁用手势处理，默认为false
 */
interface CropGestureHandlerProps {
  cropRect: SharedValue<CropRect>; // 共享值，存储裁剪框的实时位置和尺寸
  imageSize: { width: number; height: number }; // 图片的宽高尺寸
  canvasPosition: { x: number; y: number }; // Canvas在父容器中的位置
  matrix?: SharedValue<any>; // 变换矩阵共享值
  disabled?: boolean; // 手势开关，true时禁用所有手势
  toolKey?: string; // 工具类型，用于控制拖动点的显示
  isInteracting?: SharedValue<boolean>; // 是否正在交互（拖动或缩放）
}

/**
 * 裁剪框手势处理器组件
 *
 * 该组件创建一个透明的手势区域，覆盖在裁剪框上方，
 * 用于处理用户对裁剪框的拖动操作。
 *
 * @param props - 组件props，包含cropRect、imageSize等配置
 * @returns 返回一个手势检测器和透明的动画视图
 */
export const CropGestureHandler = ({
  cropRect,
  imageSize,
  canvasPosition,
  matrix,
  disabled = false,
  toolKey,
  isInteracting,
}: CropGestureHandlerProps) => {
  const startCropRect = useSharedValue<CropRect>({
    x: 0,
    y: 0,
    width: 0,
    height: 0,
  });

  // 平移手势 - 整个裁剪框移动
  const pan = Gesture.Pan()
    .enabled(!disabled)
    .onStart(() => {
      startCropRect.value = { ...cropRect.value };
      if (isInteracting) {
        isInteracting.value = true;
      }
    })
    .onFinalize(() => {
      if (isInteracting) {
        isInteracting.value = false;
      }
    })
    .onChange((e) => {
      // 检查是否已经在边缘，如果是则阻止继续拖动
      const isAtLeftEdge = cropRect.value.x <= 0;
      const isAtRightEdge =
        cropRect.value.x + cropRect.value.width >= imageSize.width;
      const isAtTopEdge = cropRect.value.y <= 0;
      const isAtBottomEdge =
        cropRect.value.y + cropRect.value.height >= imageSize.height;

      // 根据边缘状态决定是否应用位移
      let effectiveChangeX = e.changeX;
      let effectiveChangeY = e.changeY;

      if ((isAtLeftEdge && e.changeX < 0) || (isAtRightEdge && e.changeX > 0)) {
        effectiveChangeX = 0;
      }
      if ((isAtTopEdge && e.changeY < 0) || (isAtBottomEdge && e.changeY > 0)) {
        effectiveChangeY = 0;
      }

      // 计算新的裁剪框位置，确保不超出图片边界
      const newX = Math.max(
        0,
        Math.min(
          cropRect.value.x + effectiveChangeX,
          imageSize.width - cropRect.value.width
        )
      );
      const newY = Math.max(
        0,
        Math.min(
          cropRect.value.y + effectiveChangeY,
          imageSize.height - cropRect.value.height
        )
      );

      // 只有当实际位置发生变化时才更新
      if (newX !== cropRect.value.x || newY !== cropRect.value.y) {
        const newRect = {
          ...cropRect.value,
          x: newX,
          y: newY,
        };
        cropRect.value = newRect;

        // 如果有matrix共享值，同步更新
        if (matrix) {
          const newMatrix = Skia.Matrix();
          newMatrix.translate(newX, newY);
          matrix.value = newMatrix as any;
        }
      }
    });

  /**
   * 创建中点拖拽手势处理器
   * @param edge - 边缘位置
   * @returns 对应的手势处理器
   */
  const createEdgeGesture = (edge: "top" | "bottom" | "left" | "right") => {
    return Gesture.Pan()
      .enabled(!disabled)
      .onStart(() => {
        startCropRect.value = { ...cropRect.value };
        if (isInteracting) {
          isInteracting.value = true;
        }
      })
      .onFinalize(() => {
        if (isInteracting) {
          isInteracting.value = false;
        }
      })
      .onChange((e) => {
        const start = startCropRect.value;
        let newWidth = start.width;
        let newHeight = start.height;
        let newX = start.x;
        let newY = start.y;

        // 检查当前是否已经在边缘
        const isAtLeftEdge = start.x <= 0;
        const isAtRightEdge = start.x + start.width >= imageSize.width;
        const isAtTopEdge = start.y <= 0;
        const isAtBottomEdge = start.y + start.height >= imageSize.height;

        // 严格边界检查 - 确保裁剪框不能超出图像边界
        if (edge === "top") {
          // 顶部控制点：如果已经在顶部边缘且继续向上拖动，则阻止
          if (!(isAtTopEdge && e.translationY < 0)) {
            const deltaY = e.translationY;
            const originalBottomY = start.y + start.height;
            const targetTopY = start.y + deltaY;
            const clampedTopY = Math.max(
              0,
              Math.min(targetTopY, originalBottomY - 50)
            );
            newHeight = originalBottomY - clampedTopY;
            newY = clampedTopY;
          }
        } else if (edge === "bottom") {
          // 底部控制点：如果已经在底部边缘且继续向下拖动，则阻止
          if (!(isAtBottomEdge && e.translationY > 0)) {
            const deltaY = e.translationY;
            const originalTopY = start.y;
            newHeight = Math.max(
              50,
              Math.min(start.height + deltaY, imageSize.height - originalTopY)
            );
            newX = start.x;
            newY = originalTopY;
            newWidth = start.width;
          }
        } else if (edge === "left") {
          // 左侧控制点：如果已经在左侧边缘且继续向左拖动，则阻止
          if (!(isAtLeftEdge && e.translationX < 0)) {
            const deltaX = e.translationX;
            const originalRightX = start.x + start.width;
            const newLeftX = Math.max(
              0,
              Math.min(start.x + deltaX, originalRightX - 50)
            );
            newWidth = originalRightX - newLeftX;
            newX = newLeftX;
            newY = start.y;
            newHeight = start.height;
          }
        } else if (edge === "right") {
          // 右侧控制点：如果已经在右侧边缘且继续向右拖动，则阻止
          if (!(isAtRightEdge && e.translationX > 0)) {
            const deltaX = e.translationX;
            const originalLeftX = start.x;
            newWidth = Math.max(
              50,
              Math.min(start.width + deltaX, imageSize.width - originalLeftX)
            );
            newX = originalLeftX;
            newY = start.y;
            newHeight = start.height;
          }
        }

        // 只有当实际值发生变化时才更新
        if (
          newX !== start.x ||
          newY !== start.y ||
          newWidth !== start.width ||
          newHeight !== start.height
        ) {
          cropRect.value = {
            x: newX,
            y: newY,
            width: newWidth,
            height: newHeight,
          };
        }
      });
  };

  // 使用通用函数创建中点手势处理器
  const topCenterPan = createEdgeGesture("top");
  const bottomCenterPan = createEdgeGesture("bottom");
  const leftCenterPan = createEdgeGesture("left");
  const rightCenterPan = createEdgeGesture("right");

  /**
   * 解析比例字符串
   * @param ratioStr - 比例字符串如"1_1", "4_3"等
   * @returns 宽高比例数值
   */
  const parseRatio = (ratioStr?: string): number => {
    "worklet";
    if (!ratioStr || !ratioStr.includes("_")) return 0;
    const [width, height] = ratioStr.split("_").map(Number);
    return width / height;
  };

  /**
   * 创建角点拖拽手势处理器
   * @param corner - 角点位置
   * @returns 对应的手势处理器
   */
  const createCornerGesture = (
    corner: "top-left" | "top-right" | "bottom-left" | "bottom-right"
  ) => {
    return Gesture.Pan()
      .enabled(!disabled)
      .onStart(() => {
        startCropRect.value = { ...cropRect.value };
        if (isInteracting) {
          isInteracting.value = true;
        }
      })
      .onFinalize(() => {
        if (isInteracting) {
          isInteracting.value = false;
        }
      })
      .onChange((e) => {
        const ratio = parseRatio(toolKey);
        const isCropMode = toolKey === "crop";
        const deltaX = e.translationX;
        const deltaY = e.translationY;

        const start = startCropRect.value;
        let newWidth = start.width;
        let newHeight = start.height;
        let newX = start.x;
        let newY = start.y;

        // 检查当前是否已经在边缘
        const isAtLeftEdge = start.x <= 0;
        const isAtRightEdge = start.x + start.width >= imageSize.width;
        const isAtTopEdge = start.y <= 0;
        const isAtBottomEdge = start.y + start.height >= imageSize.height;

        // 根据角点位置计算新的宽高和位置，保持对角固定
        let shouldUpdate = true;

        switch (corner) {
          case "top-left":
            // 固定bottom-right角点，调整top-left
            const newRight = start.x + start.width;
            const newBottom = start.y + start.height;

            // 如果已经在对应边缘且继续向外拖动，则阻止
            if ((isAtLeftEdge && deltaX < 0) || (isAtTopEdge && deltaY < 0)) {
              shouldUpdate = false;
            } else {
              newX = Math.max(0, Math.min(start.x + deltaX, newRight - 50));
              newY = Math.max(0, Math.min(start.y + deltaY, newBottom - 50));
              newWidth = newRight - newX;
              newHeight = isCropMode
                ? newBottom - newY
                : Math.max(50, newBottom - newY);
            }
            break;
          case "top-right":
            // 固定bottom-left角点，调整top-right
            const newLeftTR = start.x;
            const newBottomTR = start.y + start.height;

            // 如果已经在对应边缘且继续向外拖动，则阻止
            if ((isAtRightEdge && deltaX > 0) || (isAtTopEdge && deltaY < 0)) {
              shouldUpdate = false;
            } else {
              newY = Math.max(0, Math.min(start.y + deltaY, newBottomTR - 50));
              newWidth = Math.max(
                50,
                Math.min(start.x + start.width + deltaX, imageSize.width) -
                  newLeftTR
              );
              newHeight = isCropMode
                ? newBottomTR - newY
                : Math.max(50, newBottomTR - newY);
              newX = newLeftTR;
            }
            break;
          case "bottom-left":
            // 固定top-right角点，调整bottom-left
            const newRightBL = start.x + start.width;
            const newTopBL = start.y;

            // 如果已经在对应边缘且继续向外拖动，则阻止
            if (
              (isAtLeftEdge && deltaX < 0) ||
              (isAtBottomEdge && deltaY > 0)
            ) {
              shouldUpdate = false;
            } else {
              newX = Math.max(0, Math.min(start.x + deltaX, newRightBL - 50));
              newY = newTopBL;
              newWidth = newRightBL - newX;
              newHeight = isCropMode
                ? Math.max(
                    50,
                    Math.min(
                      start.y + start.height + deltaY,
                      imageSize.height
                    ) - newTopBL
                  )
                : Math.max(
                    50,
                    Math.min(
                      start.y + start.height + deltaY,
                      imageSize.height
                    ) - newTopBL
                  );
            }
            break;
          case "bottom-right":
            // 固定top-left角点，调整bottom-right
            const newLeftBR = start.x;
            const newTopBR = start.y;

            // 如果已经在对应边缘且继续向外拖动，则阻止
            if (
              (isAtRightEdge && deltaX > 0) ||
              (isAtBottomEdge && deltaY > 0)
            ) {
              shouldUpdate = false;
            } else {
              newX = newLeftBR;
              newY = newTopBR;
              newWidth = Math.max(
                50,
                Math.min(start.x + start.width + deltaX, imageSize.width) -
                  newLeftBR
              );
              newHeight = isCropMode
                ? Math.max(
                    50,
                    Math.min(
                      start.y + start.height + deltaY,
                      imageSize.height
                    ) - newTopBR
                  )
                : Math.max(
                    50,
                    Math.min(
                      start.y + start.height + deltaY,
                      imageSize.height
                    ) - newTopBR
                  );
            }
            break;
        }

        // 只有当允许更新时才继续处理
        if (shouldUpdate) {
          // 比例模式下处理 - 仅在非自由模式下应用比例约束
          if (ratio > 0 && !isCropMode) {
            switch (corner) {
              case "top-left":
                // 固定bottom-right，调整top-left，严格保持比例
                const fixedRightBR = start.x + start.width;
                const fixedBottomBR = start.y + start.height;

                // 计算最大可能的宽度和高度（考虑边界约束）
                const maxWidthBR = fixedRightBR - 0; // 左边界限制
                const maxHeightBR = fixedBottomBR - 0; // 上边界限制

                // 基于拖动方向和距离计算新的宽高
                let targetWidthBR = fixedRightBR - (start.x + deltaX);
                let targetHeightBR = targetWidthBR / ratio;

                // 检查是否会超过边界，如果会则按边界约束计算
                if (targetHeightBR > maxHeightBR) {
                  targetHeightBR = maxHeightBR;
                  targetWidthBR = targetHeightBR * ratio;
                }
                if (targetWidthBR > maxWidthBR) {
                  targetWidthBR = maxWidthBR;
                  targetHeightBR = targetWidthBR / ratio;
                }

                // 根据比例动态计算最小宽高
                const minDimension = 50;
                let minWidth, minHeight;
                
                if (ratio === 1) {
                  // 1:1 比例
                  minWidth = minDimension;
                  minHeight = minDimension;
                } else if (ratio > 1) {
                  // 宽大于高，如4:3
                  minHeight = minDimension;
                  minWidth = minDimension * ratio;
                } else {
                  // 高大于宽，如3:4
                  minWidth = minDimension;
                  minHeight = minDimension / ratio;
                }
                
                console.log('比例模式下最小宽高计算(BR):', {
                  ratio,
                  minWidth,
                  minHeight,
                  targetWidthBR,
                  targetHeightBR
                });
                
                // 确保最小尺寸，禁止继续缩小
                if (targetWidthBR < minWidth || targetHeightBR < minHeight) {
                  targetWidthBR = Math.max(minWidth, 50);
                  targetHeightBR = Math.max(minHeight, 50);
                }

                // 重新计算位置以保持bottom-right固定且比例严格
                newWidth = Math.max(targetWidthBR, minWidth, 50);
                newHeight = Math.max(targetHeightBR, minHeight, 50);
                newX = fixedRightBR - newWidth;
                newY = fixedBottomBR - newHeight;
                break;

              case "top-right":
                // 固定bottom-left，调整top-right，严格保持比例
                const fixedLeftBL = start.x;
                const fixedBottomBL = start.y + start.height;

                // 计算最大可能的宽度和高度（考虑边界约束）
                const maxWidthBL = imageSize.width - fixedLeftBL; // 右边界限制
                const maxHeightBL = fixedBottomBL - 0; // 上边界限制

                // 基于拖动方向和距离计算新的宽高
                let targetWidthBL =
                  start.x + start.width + deltaX - fixedLeftBL;
                let targetHeightBL = targetWidthBL / ratio;

                // 检查是否会超过边界，如果会则按边界约束计算
                if (targetHeightBL > maxHeightBL) {
                  targetHeightBL = maxHeightBL;
                  targetWidthBL = targetHeightBL * ratio;
                }
                if (targetWidthBL > maxWidthBL) {
                  targetWidthBL = maxWidthBL;
                  targetHeightBL = targetWidthBL / ratio;
                }

                // 根据比例动态计算最小宽高
                const minDimensionBL = 50;
                let minWidthBL, minHeightBL;
                
                if (ratio === 1) {
                  // 1:1 比例
                  minWidthBL = minDimensionBL;
                  minHeightBL = minDimensionBL;
                } else if (ratio > 1) {
                  // 宽大于高，如4:3
                  minHeightBL = minDimensionBL;
                  minWidthBL = minDimensionBL * ratio;
                } else {
                  // 高大于宽，如3:4
                  minWidthBL = minDimensionBL;
                  minHeightBL = minDimensionBL / ratio;
                }
                
                console.log('比例模式下最小宽高计算(BL):', {
                  ratio,
                  minWidth: minWidthBL,
                  minHeight: minHeightBL,
                  targetWidth: targetWidthBL,
                  targetHeight: targetHeightBL
                });
                
                // 确保最小尺寸，禁止继续缩小
                if (targetWidthBL < minWidthBL || targetHeightBL < minHeightBL) {
                  targetWidthBL = Math.max(minWidthBL, 50);
                  targetHeightBL = Math.max(minHeightBL, 50);
                }

                // 重新计算位置以保持bottom-left固定且比例严格
                newWidth = Math.max(targetWidthBL, minWidthBL, 50);
                newHeight = Math.max(targetHeightBL, minHeightBL, 50);
                newX = fixedLeftBL;
                newY = fixedBottomBL - newHeight;
                break;

              case "bottom-left":
                // 固定top-right，调整bottom-left，严格保持比例
                const fixedRightTR = start.x + start.width;
                const fixedTopTR = start.y;

                // 计算最大可能的宽度和高度（考虑边界约束）
                const maxWidthTR = fixedRightTR - 0; // 左边界限制
                const maxHeightTR = imageSize.height - fixedTopTR; // 下边界限制

                // 基于拖动方向和距离计算新的宽高
                let targetWidthTR = fixedRightTR - (start.x + deltaX);
                let targetHeightTR =
                  start.y + start.height + deltaY - fixedTopTR;
                targetHeightTR = targetWidthTR / ratio;

                // 检查是否会超过边界，如果会则按边界约束计算
                if (targetWidthTR > maxWidthTR) {
                  targetWidthTR = maxWidthTR;
                  targetHeightTR = targetWidthTR / ratio;
                }
                if (targetHeightTR > maxHeightTR) {
                  targetHeightTR = maxHeightTR;
                  targetWidthTR = targetHeightTR * ratio;
                }

                // 根据比例动态计算最小宽高
                const minDimensionTR = 50;
                let minWidthTR, minHeightTR;
                
                if (ratio === 1) {
                  // 1:1 比例
                  minWidthTR = minDimensionTR;
                  minHeightTR = minDimensionTR;
                } else if (ratio > 1) {
                  // 宽大于高，如4:3
                  minHeightTR = minDimensionTR;
                  minWidthTR = minDimensionTR * ratio;
                } else {
                  // 高大于宽，如3:4
                  minWidthTR = minDimensionTR;
                  minHeightTR = minDimensionTR / ratio;
                }
                
                console.log('比例模式下最小宽高计算(TR):', {
                  ratio,
                  minWidth: minWidthTR,
                  minHeight: minHeightTR,
                  targetWidth: targetWidthTR,
                  targetHeight: targetHeightTR
                });
                
                // 确保最小尺寸，禁止继续缩小
                if (targetWidthTR < minWidthTR || targetHeightTR < minHeightTR) {
                  targetWidthTR = Math.max(minWidthTR, 50);
                  targetHeightTR = Math.max(minHeightTR, 50);
                }

                // 重新计算位置以保持top-right固定且比例严格
                newWidth = Math.max(targetWidthTR, minWidthTR, 50);
                newHeight = Math.max(targetHeightTR, minHeightTR, 50);
                newX = fixedRightTR - newWidth;
                newY = fixedTopTR;
                break;

              case "bottom-right":
                // 固定top-left，调整bottom-right，严格保持比例
                const fixedLeftTL = start.x;
                const fixedTopTL = start.y;

                // 计算最大可能的宽度和高度（考虑边界约束）
                const maxWidthTL = imageSize.width - fixedLeftTL; // 右边界限制
                const maxHeightTL = imageSize.height - fixedTopTL; // 下边界限制

                // 基于拖动方向和距离计算新的宽高
                let targetWidthTL =
                  start.x + start.width + deltaX - fixedLeftTL;
                let targetHeightTL =
                  start.y + start.height + deltaY - fixedTopTL;
                targetHeightTL = targetWidthTL / ratio;

                // 检查是否会超过边界，如果会则按边界约束计算
                if (targetWidthTL > maxWidthTL) {
                  targetWidthTL = maxWidthTL;
                  targetHeightTL = targetWidthTL / ratio;
                }
                if (targetHeightTL > maxHeightTL) {
                  targetHeightTL = maxHeightTL;
                  targetWidthTL = targetHeightTL * ratio;
                }

                // 根据比例动态计算最小宽高
                const minDimensionTL = 50;
                let minWidthTL, minHeightTL;
                
                if (ratio === 1) {
                  // 1:1 比例
                  minWidthTL = minDimensionTL;
                  minHeightTL = minDimensionTL;
                } else if (ratio > 1) {
                  // 宽大于高，如4:3
                  minHeightTL = minDimensionTL;
                  minWidthTL = minDimensionTL * ratio;
                } else {
                  // 高大于宽，如3:4
                  minWidthTL = minDimensionTL;
                  minHeightTL = minDimensionTL / ratio;
                }
                
                console.log('比例模式下最小宽高计算(TL):', {
                  ratio,
                  minWidth: minWidthTL,
                  minHeight: minHeightTL,
                  targetWidth: targetWidthTL,
                  targetHeight: targetHeightTL
                });
                
                // 确保最小尺寸，禁止继续缩小
                if (targetWidthTL < minWidthTL || targetHeightTL < minHeightTL) {
                  targetWidthTL = Math.max(minWidthTL, 50);
                  targetHeightTL = Math.max(minHeightTL, 50);
                }

                // 重新计算位置以保持top-left固定且比例严格
                newWidth = Math.max(targetWidthTL, minWidthTL, 50);
                newHeight = Math.max(targetHeightTL, minHeightTL, 50);
                newX = fixedLeftTL;
                newY = fixedTopTL;
                break;
            }
          }

          // 平滑边界处理：直接约束坐标到有效范围
          const constrainedX = Math.max(
            0,
            Math.min(newX, imageSize.width - newWidth)
          );
          const constrainedY = Math.max(
            0,
            Math.min(newY, imageSize.height - newHeight)
          );
          const constrainedWidth = Math.max(
            50,
            Math.min(newWidth, imageSize.width - constrainedX)
          );
          const constrainedHeight = Math.max(
            50,
            Math.min(newHeight, imageSize.height - constrainedY)
          );

          // 只有当实际值发生变化时才更新
          if (
            constrainedX !== start.x ||
            constrainedY !== start.y ||
            constrainedWidth !== start.width ||
            constrainedHeight !== start.height
          ) {
            cropRect.value = {
              ...cropRect.value,
              x: constrainedX,
              y: constrainedY,
              width: constrainedWidth,
              height: constrainedHeight,
            };
          }
        }
      });
  };

  // 使用通用函数创建角点手势处理器
  const topLeftPan = createCornerGesture("top-left");
  const topRightPan = createCornerGesture("top-right");
  const bottomLeftPan = createCornerGesture("bottom-left");
  const bottomRightPan = createCornerGesture("bottom-right");

  const style = useAnimatedStyle(() => ({
    position: "absolute" as const,
    width: cropRect.value.width,
    height: cropRect.value.height,
    top: cropRect.value.y,
    left: cropRect.value.x,
    zIndex: 1000,
  }));

  // 为每个控制点创建独立的动画样式
  const topLeftStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x,
      top: rect.y,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const topRightStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x + rect.width - width,
      top: rect.y,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const bottomLeftStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x,
      top: rect.y + rect.height - height,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const bottomRightStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x + rect.width - width,
      top: rect.y + rect.height - height,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const topCenterStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 30;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x + rect.width / 2 - width / 2,
      top: rect.y,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const bottomCenterStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 30;
    const height = 20;
    return {
      position: "absolute" as const,
      left: rect.x + rect.width / 2 - width / 2,
      top: rect.y + rect.height - height,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const leftCenterStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 30;
    return {
      position: "absolute" as const,
      left: rect.x,
      top: rect.y + rect.height / 2 - height / 2,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  const rightCenterStyle = useAnimatedStyle(() => {
    const rect = cropRect.value;
    const width = 20;
    const height = 30;
    return {
      position: "absolute" as const,
      left: rect.x + rect.width - width,
      top: rect.y + rect.height / 2 - height / 2,
      width,
      height,
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: 0,
      zIndex: 1001,
    };
  });

  /**
   * 根据toolKey获取需要显示的控制点
   * @param toolKey - 工具类型标识
   * @returns 需要显示的控制点位置数组
   */
  const getVisibleControlPoints = (toolKey?: string): string[] => {
    if (!toolKey) return [];

    switch (toolKey) {
      case "crop":
        // 显示所有控制点（四个角 + 四条边中点）
        return [
          "top-left",
          "top-right",
          "bottom-left",
          "bottom-right",
          "top-center",
          "bottom-center",
          "left-center",
          "right-center",
        ];
      case "original":
        // 隐藏所有控制点
        return [];
      default:
        // 比例模式（如1_1, 4_3等）只显示四个角的控制点
        if (toolKey.includes("_")) {
          return ["top-left", "top-right", "bottom-left", "bottom-right"];
        }
        // 其他情况显示所有控制点
        return [
          "top-left",
          "top-right",
          "bottom-left",
          "bottom-right",
          "top-center",
          "bottom-center",
          "left-center",
          "right-center",
        ];
    }
  };

  const visibleControlPoints = getVisibleControlPoints(toolKey);

  // 定义控制点配置数组，用于动态渲染
  const controlPoints = [
    { position: "top-left", gesture: topLeftPan, style: topLeftStyle },
    { position: "top-right", gesture: topRightPan, style: topRightStyle },
    { position: "bottom-left", gesture: bottomLeftPan, style: bottomLeftStyle },
    {
      position: "bottom-right",
      gesture: bottomRightPan,
      style: bottomRightStyle,
    },
    { position: "top-center", gesture: topCenterPan, style: topCenterStyle },
    {
      position: "bottom-center",
      gesture: bottomCenterPan,
      style: bottomCenterStyle,
    },
    { position: "left-center", gesture: leftCenterPan, style: leftCenterStyle },
    {
      position: "right-center",
      gesture: rightCenterPan,
      style: rightCenterStyle,
    },
  ];

  return (
    <>
      {/* 裁剪框区域手势 */}
      <GestureDetector gesture={pan}>
        <Animated.View style={style} />
      </GestureDetector>

      {/* 根据toolKey动态渲染控制点 */}
      {controlPoints.map(
        ({ position, gesture, style }) =>
          visibleControlPoints.includes(position) && (
            <GestureDetector key={position} gesture={gesture}>
              <Animated.View style={style} />
            </GestureDetector>
          )
      )}
    </>
  );
};